package com.summer.campussct.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.summer.campussct.mapper.CategoryMapper;
import com.summer.campussct.pojo.*;
import com.summer.campussct.mapper.VehiclePublishMapper;
import com.summer.campussct.pojo.dto.CategoryPublishDto;
import com.summer.campussct.pojo.dto.RestResult;
import com.summer.campussct.pojo.dto.VehicleQueryParams;
import com.summer.campussct.service.*;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * <p>
 * 车辆发布表 服务实现类
 * </p>
 *
 * @author Mr.Chen
 * @since 2024-05-10
 */
@Service
public class VehiclePublishServiceImpl extends ServiceImpl<VehiclePublishMapper, VehiclePublish> implements IVehiclePublishService {

    @Resource
    private IVehicleService vehicleService;

    @Resource
    private IVehicleMarketService vehicleMarketService;

    @Resource
    private IVehicleAuditService vehicleAuditService;

    @Resource
    private ICategoryService categoryService;

    @Resource
    private ICampusOrShopService campusOrShopService;

    @Resource
    private IUserService userService;

    @Resource
    private VehiclePublishMapper vehiclePublishMapper;

    @Resource
    private CategoryMapper categoryMapper;

    @Override
    @Transactional
    public RestResult publishVehicle(long id) {
        //1. 查询审核表
        VehicleAudit vehicleAudit = vehicleAuditService.getOne(new LambdaQueryWrapper<VehicleAudit>()
                        .eq(VehicleAudit::getVid, id));
        //2. 校验：审核成功才能发布
        if (vehicleAudit.getAuditStatus() == 20004 && vehicleAudit.getPublishStatus() == 30001){
            // 查询vehicle
            Vehicle vehicle = vehicleService.getById(id);
            // 查询vehicleMarket
            VehicleMarket vehicleMarket = vehicleMarketService.getOne(new LambdaQueryWrapper<VehicleMarket>()
                    .eq(VehicleMarket::getVid, id));
            Long vehicleCategoryId = vehicleMarket.getVehicleCategoryId();
            // 查询Category
            Category category = categoryService.getById(vehicleCategoryId);

            // 查询user
            Long uid = vehicleMarket.getUid();
            User user = userService.getOne(new LambdaQueryWrapper<User>()
                    .select(User::getId, User::getNickname, User::getAccount, User::getAvatar)
                    .eq(User::getId, uid));

            //3. 新增
            //3.1 封装数据
            VehiclePublish vehiclePublish = new VehiclePublish();

            // 如果关联了学校或车商，则查询campusOrShop并添加到publish表中
            Long campusOrShopId = vehicleMarket.getCampusOrShopId();
            if (campusOrShopId != null){
                CampusOrShop campusOrShop = campusOrShopService.getById(campusOrShopId);
                vehiclePublish.setCampusOrShopType(campusOrShop.getType());
                vehiclePublish.setCampusOrShopName(campusOrShop.getName());
                vehiclePublish.setCampusOrShopAddr(campusOrShop.getAddr());
                vehiclePublish.setCampusOrShopPicture(campusOrShop.getPicture());
            }

            BeanUtil.copyProperties(vehicle, vehiclePublish, CopyOptions.create().ignoreNullValue());
            BeanUtil.copyProperties(vehicleMarket, vehiclePublish, CopyOptions.create().ignoreNullValue());
            BeanUtil.copyProperties(user, vehiclePublish, CopyOptions.create().ignoreNullValue());

            vehiclePublish.setVehicleName(vehicle.getName());
            vehiclePublish.setVid(vehicle.getId());
            vehiclePublish.setVehicleCategoryName(category.getName());
            vehiclePublish.setBrandName(vehicle.getBrand());
            vehiclePublish.setPublishStatus(30002);
            // 将id置空再添加，防止其他Bean的id copy到发布表的id字段上
            vehiclePublish.setId(null);

            //3.2 将audit表中的发布状态改为已发布
            boolean update = vehicleAuditService.update(new LambdaUpdateWrapper<VehicleAudit>()
                    .set(VehicleAudit::getPublishStatus, 30002)
                    .eq(VehicleAudit::getVid, id));
            if (!update) throw new RuntimeException("修改audit表");

            boolean save = this.save(vehiclePublish);
            if (!save) throw new RuntimeException("新增发布表失败");

            return RestResult.success();
        } else {
            throw new RuntimeException("发布失败: 审核状态或发布状态不合法");
        }
    }

    @Override
    @Transactional
    public RestResult modifyPrice(Long vid, BigDecimal price) {
        //1. 状态为已发布才能修改
        VehiclePublish vehiclePublish = this.getOne(new LambdaQueryWrapper<VehiclePublish>()
                .select(VehiclePublish::getPublishStatus)
                .eq(VehiclePublish::getVid, vid));
        if (vehiclePublish == null || vehiclePublish.getPublishStatus() != 30002){
            throw new RuntimeException("无法修改价格");
        }
        //2. 修改vehicleMarket
        boolean update = vehicleMarketService.update(new LambdaUpdateWrapper<VehicleMarket>()
                .set(VehicleMarket::getCurrentPrice, price)
                .eq(VehicleMarket::getVid, vid));
        if (!update) throw new RuntimeException("修改价格失败");

        //3. 修改publish
        boolean update1 = this.update(new LambdaUpdateWrapper<VehiclePublish>()
                .set(VehiclePublish::getCurrentPrice, price)
                .eq(VehiclePublish::getVid, vid));
        if (!update1) throw new RuntimeException("修改价格失败");

        return RestResult.success();
    }

    @Override
    @Transactional
    public RestResult offlineVehicle(long id) {
        // 只有已发布才能下架
        VehiclePublish vehiclePublish = this.getOne(new LambdaQueryWrapper<VehiclePublish>()
                .select(VehiclePublish::getPublishStatus)
                .eq(VehiclePublish::getVid, id));
        if (vehiclePublish == null || vehiclePublish.getPublishStatus() != 30002){
            throw new RuntimeException("无法修改价格");
        }

        // 修改audit状态
        boolean update = vehicleAuditService.update(new LambdaUpdateWrapper<VehicleAudit>()
                .set(VehicleAudit::getPublishStatus, 30004)
                .eq(VehicleAudit::getVid, id));
        if (!update) throw new RuntimeException("下架车辆失败");

        // 修改publish状态
        boolean update1 = this.update(new LambdaUpdateWrapper<VehiclePublish>()
                .set(VehiclePublish::getPublishStatus, 30004)
                .eq(VehiclePublish::getVid, id));
        if (!update1) throw new RuntimeException("下架车辆失败");
        return RestResult.success();
    }

    @Override
    @Transactional
    public RestResult rePublishVehicle(long id) {
        // 只有状态为下架的车辆才能重新发布
        VehiclePublish vehiclePublish = this.getOne(new LambdaQueryWrapper<VehiclePublish>()
                .select(VehiclePublish::getPublishStatus)
                .eq(VehiclePublish::getVid, id));
        if (vehiclePublish == null || vehiclePublish.getPublishStatus() != 30004){
            throw new RuntimeException("无法重新发布");
        }

        // 修改audit状态
        boolean update = vehicleAuditService.update(new LambdaUpdateWrapper<VehicleAudit>()
                .set(VehicleAudit::getPublishStatus, 30002)
                .eq(VehicleAudit::getVid, id));
        if (!update) throw new RuntimeException("重新发布车辆失败");

        // 修改publish状态
        boolean update1 = this.update(new LambdaUpdateWrapper<VehiclePublish>()
                .set(VehiclePublish::getPublishStatus, 30002)
                .eq(VehiclePublish::getVid, id));
        if (!update1) throw new RuntimeException("重新发布车辆失败");
        return RestResult.success();
    }

    @Override
    public RestResult getNewList() {
        List<VehiclePublish> newList = vehiclePublishMapper.getNewList();
        return RestResult.success(newList);

    }

    @Override
    public RestResult getDetails(long id) {
        VehiclePublish vehiclePublish = vehiclePublishMapper.getDetails(id);
        return RestResult.success(vehiclePublish);
    }

    @Override
    public RestResult getCategoryData(int id) {
        //1. 先查询某个分类下的子分类
        List<Long> subCategoryIdList = categoryMapper.getSubCategoryListById(id);

        //2. 根据子分类id一个一个查询，并将结果存入集合中
        ArrayList<CategoryPublishDto> categoryPublishDtoList = new ArrayList<>();
        for (Long subCategoryId : subCategoryIdList) {
            CategoryPublishDto categoryPublishDto = vehiclePublishMapper.getCategoryPublishDto(subCategoryId);
            // 这一步判断很重要，不然列表就会加入null
            if (categoryPublishDto != null){
                categoryPublishDtoList.add(categoryPublishDto);
            }
        }

        return RestResult.success(categoryPublishDtoList);
    }

    @Override
    public RestResult listByCondition(VehicleQueryParams vehicleQueryParams) {

        Integer currentPage = vehicleQueryParams.getCurrentPage();
        currentPage = vehicleQueryParams.getPageSize() * (currentPage - 1);
        vehicleQueryParams.setCurrentPage(currentPage);

        return RestResult.success(vehiclePublishMapper.listByCondition(vehicleQueryParams));
    }

    @Override
    public RestResult orderCar(long id) {
        VehiclePublish vehiclePublish = this.getOne(new LambdaQueryWrapper<VehiclePublish>()
                .select(VehiclePublish::getId,
                        VehiclePublish::getVid,
                        VehiclePublish::getVehicleName,
                        VehiclePublish::getVersion,
                        VehiclePublish::getEmissionStandard,
                        VehiclePublish::getTradeAddr,
                        VehiclePublish::getCampusOrShopName,
                        VehiclePublish::getTelNum,
                        VehiclePublish::getLeaveMessage,
                        VehiclePublish::getCurrentPrice,
                        VehiclePublish::getFrontPic,
                        VehiclePublish::getOrderPrice)
                .eq(VehiclePublish::getVid, id)
                .eq(VehiclePublish::getPublishStatus, 30002));
        if (vehiclePublish == null) return RestResult.error("车辆不存在");
        return RestResult.success(vehiclePublish);
    }
}
